import aphw._aphw as impl

import aphw
from aphw.util import return_status

@return_status
def _begin(db, flags):
    return impl.begin_txn(db, flags)

@return_status
def _commit(db):
    return impl.commit_txn(db)

@return_status
def _abort(db):
    return impl.abort_txn(db)

class Transaction(object):
    def __init__(self, db, read_only=False):
        self.db = db

        flags = 0
        if read_only:
            flags |= aphw.Flags.TXN_READ_ONLY

        err = _begin(self.db._db, flags)
        if err != impl.StatusCodes.SUCCESS:
            raise aphw.StatusError(err, 
                                   'Error beginning transaction')

        self.__active = True

    def commit(self):
        if not self.__active:
            raise aphw.TransactionError('Attempting to commit inactive transaction')

        err = _commit(self.db._db)
        if err != impl.StatusCodes.SUCCESS:
            raise aphw.StatusError(err,
                                   'Error committing transaction')

        self.__active = False

    def abort(self):
        if not self.__active:
            raise aphw.TransactionError('Attempting to abort inactive transaction')

        err = _abort(self.db._db)
        if err != impl.StatusCodes.SUCCESS:
            raise aphw.StatusError(err,
                                   'Error aborting transaction')

        self.__active = False

    def __enter__(self):
        return self

    def __exit__(self, type, instance, traceback):
        if type:
            self.abort()
        else:
            self.commit()

        return False
